"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 硬件故障类--网卡
Case Name   : TPCC过程主机网卡中断3分钟
Create At   : 2020-10-28
Owner       : n@ningyali
Description :
    1、执行tpcc
    2、停止DN主网卡3分钟
    3、验证tpcc执行结果
    4、故障消除后，查询数据库状态
    5、再次执行tpcc
Expect      :
    1、执行tpcc，开始执行
    2、停止DN主网卡3分钟，执行成功
    3、验证tpcc执行结果，执行成功
    4、故障消除后，查询数据库状态正常
    5、再次执行tpcc成功
History     :
    modified：2021-9-3 by 5328113;cfe注入故障返回结果变更，优化查询网卡及断言；
    主机网卡故障tpcc本身执行并不异常，可能会存在锁超时ERROR,属于正常报错，修改tpcc结果断言；
    created： 2020/10/28  created by n@ningyali
    2021/1/20 @wan005:网卡异常时tpcc会中断
    modified：2022-5-25 by 5328113;优化用例，执行tpcc后等待5s，保证tpcc过程注入网卡故障，最终tpcc执行成功
"""

import os
import time
import unittest

from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.CommonSH import RestartDbCluster
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node, macro


class PrimaryNodeNetDown(unittest.TestCase):
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pri_root = Node(node='PrimaryRoot')
        self.pri_dbuser = Node(node='PrimaryDbUser')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.sta1_sh = CommonSH('Standby1DbUser')
        self.sta2_sh = CommonSH('Standby2DbUser')
        self.com = Common()
        self.constant = Constant()

    def test_main(self):
        step_txt = '----step1:执行tpcc;expect:开始执行----'
        self.log.info(step_txt)
        tpcc_thread = ComThread(self.com.startTPCC, args=(self.pri_root,
                                                          macro.TPCC_PATH))
        tpcc_thread.setDaemon(True)
        tpcc_thread.start()
        time.sleep(5)

        step_txt = '----step2:停止DN主网卡3分钟; expect:执行成功----'
        self.log.info(step_txt)
        self.log.info("--获取网卡--")
        shell_cmd = "ifconfig"
        self.log.info(shell_cmd)
        msg = self.pri_root.sh(shell_cmd).result()
        network_card_list = msg.split('\n\n')
        self.log.info(network_card_list)
        network_card = ''
        for network_card_item in network_card_list:
            if self.pri_root.db_host in network_card_item:
                network_card = network_card_item.split(':')[0].strip()
                self.log.info(network_card)
        self.log.info("--停止DN主网卡3分钟--")
        inject_command = f"rNet_down (dev, time)values({network_card}, 180)"
        msg = self.com.cfe_inject(self.pri_root, inject_command)
        self.log.info(msg)
        self.assertIn(self.constant.cfe_inject_netdown_success_msg, msg,
                      "执行失败" + step_txt)

        self.log.info("--等待网卡故障结束--")
        time.sleep(180)

        step_txt = '----step3:验证tpcc执行结果;expect:执行成功----'
        self.log.info(step_txt)
        tpcc_thread.join(int(macro.TPCC_RUN_MAX_TIME) * 3)
        tpcc_result = tpcc_thread.get_result()
        self.log.info(tpcc_result)
        self.assertIn(self.constant.TPCC_SUCCESS_MSG, tpcc_result,
                      "执行失败" + step_txt)

        step_txt = '----step4:故障消除后，查询数据库状态;expect:状态正常----'
        self.log.info(step_txt)
        status = self.pri_sh.getDbClusterStatus('status')
        self.assertTrue(status, "执行失败" + step_txt)

        step_txt = '----step5:再次执行tpcc;expect:执行成功----'
        self.log.info(step_txt)
        tpcc_result = self.com.startTPCC(self.pri_root, macro.TPCC_PATH)
        self.log.info(tpcc_result)
        self.assertIn(self.constant.TPCC_SUCCESS_MSG, tpcc_result,
                      "执行失败" + step_txt)

    def tearDown(self):
        step1_txt = '----step6:校验刷脏页是否完成;expect:刷新完成----'
        self.log.info(step1_txt)
        dirty_page_check = self.pri_sh.check_whether_remain_dirty_page()

        step2_txt = '----step7:校验备机是否完成数据同步;expect:同步完成----'
        self.log.info(step2_txt)
        flag_1 = self.sta1_sh.check_data_consistency()
        flag_2 = self.sta2_sh.check_data_consistency()
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
        self.assertTrue(dirty_page_check, "执行失败" + step1_txt)
        self.assertTrue(flag_1, "执行失败" + step2_txt)
        self.assertTrue(flag_2, "执行失败" + step2_txt)
